package com.chutoutian.service.impl;

import com.chutoutian.enumeration.OrdersStatus;
import com.chutoutian.enumeration.PayMethod;
import com.chutoutian.exception.VailException;
import com.chutoutian.mapper.OrdersItemMapper;
import com.chutoutian.mapper.OrdersMapper;
import com.chutoutian.mapper.ProductMapper;
import com.chutoutian.po.*;
import com.chutoutian.service.AddressService;
import com.chutoutian.service.CartService;
import com.chutoutian.untils.SnowflakeIdWorker;
import com.chutoutian.vo.Cart;
import com.chutoutian.vo.CartItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.*;


@Service
public class CartServiceImpl implements CartService {

    private Logger logger = LoggerFactory.getLogger(CartServiceImpl.class.getName());

    @Resource
    private ProductMapper productMapper;

    @Resource
    private AddressService addressService;

    @Resource
    private OrdersMapper ordersMapper;

    @Resource
    private OrdersItemMapper ordersItemMapper;

    @Override
    public void addItem(String id, HttpSession session) {
        Cart cart = (Cart) session.getAttribute("cart");
        Map<String, CartItem> map = cart.getCartItemMap();
        if (StringUtils.isEmpty(map.get(id))) {
            Product product = productMapper.selectById(id);
            CartItem cartItem = new CartItem(product);
            cartItem.setNum(1);
            map.put(id, cartItem);
        } else {
            CartItem product = map.get(id);
            product.setNum(product.getNum() + 1);
        }
    }

    @Override
    public void deleteItem(String id, HttpSession session) {
        Cart cart = (Cart) session.getAttribute("cart");
        Map<String, CartItem> map = cart.getCartItemMap();
        map.remove(id);
    }

    @Override
    public void updateItem(String id, Integer num, HttpSession session) {
        Cart cart = (Cart) session.getAttribute("cart");
        Map<String, CartItem> map = cart.getCartItemMap();
        if (StringUtils.isEmpty(id)) {
            return;
        }
        CartItem product = map.get(id);
        product.setNum(num);
    }

    @Override
    public void selectedItem(String ids, HttpSession session) {
        Cart cart = (Cart) session.getAttribute("cart");

        for (String item : ids.split("\\|")) {
            cart.getCartItemMap().get(item).setChecked(true);
        }
    }

    @Override
    public void unSelectedItem(String ids, HttpSession session) {
        Cart cart = (Cart) session.getAttribute("cart");
        for (String item : ids.split("\\|")) {
            cart.getCartItemMap().get(item).setChecked(false);
        }
    }



    @Override
    public Map<String, Object> getOrders(HttpSession session) throws Exception {

        Map<String, Object> result = new HashMap<>();
        Cart cart = (Cart) session.getAttribute("cart");

        Address addressParam = new Address();
        addressParam.setUserId(cart.getUserId());
        addressParam.setIsDefault("1");
        List<Address> addressList = addressService.find(addressParam);
        if (addressList.size() == 0) {
            throw new VailException("請設置默認地址");
        }
        Address address = addressList.get(0);
        result.put("address", address);

        List<CartItem> cartItemList = new ArrayList<>();
        double productPrice = 0;
        for (CartItem item : cart.getCartItemMap().values()) {
            if (item.isChecked()) {
                cartItemList.add(item);
                productPrice += (item.getPrice() * item.getNum());
            }
        }
        double postagePrice = productPrice > 109 ? 0 : 10;
        double insurancePrice = 0;
        double cashBackPrice = 0;
        double couponsPrice = 0;
        double total = productPrice + postagePrice - insurancePrice - cashBackPrice - couponsPrice;

        result.put("productList", cartItemList);
        result.put("productPrice", productPrice);
        result.put("postagePrice", postagePrice);
        result.put("insurancePrice", insurancePrice);
        result.put("cashBackPrice", cashBackPrice);
        result.put("couponsPrice", couponsPrice);
        result.put("total", total);
        return result;
    }

    @Override
    public Orders addOrders(HttpSession session) throws Exception {
        Map<String, Object> ordersMap = getOrders(session);
        User user = (User) session.getAttribute("user");
        Cart cart = (Cart) session.getAttribute("cart");

        List<CartItem> cartItemList = (List<CartItem>) ordersMap.get("productList");
        Double productPrice = (Double) ordersMap.get("productPrice");
        Double postagePrice = (Double) ordersMap.get("postagePrice");
        Double insurancePrice = (Double) ordersMap.get("insurancePrice");
        Double cashBackPrice = (Double) ordersMap.get("cashBackPrice");
        Double couponsPrice = (Double) ordersMap.get("couponsPrice");
        Double total = (Double) ordersMap.get("total");

        Address address = (Address) ordersMap.get("address");

        Orders orders = new Orders();
        orders.setId(SnowflakeIdWorker.getId());
        orders.setStatus(OrdersStatus.DELIVERY.getId());
        orders.setCreateTime(new Date());
        orders.setAddressId(address.getId());
        orders.setInsurance(insurancePrice);
        orders.setCashBack(cashBackPrice);
        orders.setCoupons(couponsPrice);
        orders.setPayMethod(PayMethod.ARRIVAL_PAY.getId());
        orders.setPostage(postagePrice);
        orders.setProductPrice(productPrice);
        orders.setTotalPrice(total);
        orders.setUserId(user.getId());
        Integer totalNum = 0;
        for (CartItem item : cartItemList) {
            OrdersItem ordersItem = new OrdersItem();
            ordersItem.setId(SnowflakeIdWorker.getId());
            ordersItem.setOrdersId(orders.getId());
            ordersItem.setProductId(item.getProductId());
            ordersItem.setNum(item.getNum());
            ordersItem.setCreateTime(new Date());
            ordersItemMapper.insert(ordersItem);
            totalNum += item.getNum();
        }
        orders.setTotalNum(totalNum);
        ordersMapper.insert(orders);
        for (CartItem item : cartItemList) {
            cart.getCartItemMap().remove(item.getProductId());
        }
        return orders;
    }

    @Override
    public List<CartItem> get(HttpSession session) {
        Cart cart = (Cart) session.getAttribute("cart");
        return new ArrayList(cart.getCartItemMap().values());
    }

    @Override
    public Integer getNum(HttpSession session) {
        int sum = 0;
        Cart cart = (Cart) session.getAttribute("cart");
        for (CartItem item : cart.getCartItemMap().values()) {
            sum += item.getNum();
        }
        return sum;
    }
}
